package com.xstudio.pvzreborn.world.tree;

import com.xstudio.pvzreborn.PVZReborn;
import net.minecraft.core.Holder;
import net.minecraft.data.worldgen.features.FeatureUtils;
import net.minecraft.data.worldgen.placement.PlacementUtils;
import net.minecraft.data.worldgen.placement.VegetationPlacements;
import net.minecraft.util.valueproviders.ConstantInt;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
import net.minecraft.world.level.levelgen.feature.Feature;
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration;
import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration;
import net.minecraft.world.level.levelgen.feature.configurations.TreeConfiguration.TreeConfigurationBuilder;
import net.minecraft.world.level.levelgen.feature.featuresize.TwoLayersFeatureSize;
import net.minecraft.world.level.levelgen.feature.foliageplacers.BlobFoliagePlacer;
import net.minecraft.world.level.levelgen.feature.stateproviders.BlockStateProvider;
import net.minecraft.world.level.levelgen.feature.trunkplacers.StraightTrunkPlacer;
import net.minecraft.world.level.levelgen.placement.InSquarePlacement;
import net.minecraft.world.level.levelgen.placement.PlacedFeature;

public class TreeFeatures {

    public static Holder<ConfiguredFeature<TreeConfiguration, ?>> CHERRY;
    public static Holder<ConfiguredFeature<TreeConfiguration, ?>> NUT;
    public static Holder<ConfiguredFeature<TreeConfiguration, ?>> STAR_FRUIT;

    public static void registerTreeConfig() {
        CHERRY = register("cherry", Feature.TREE, treeBuilder(Blocks.BEDROCK, Blocks.BEDROCK, 4, 2, 0, 2).build());
        NUT = register("nut", Feature.TREE, treeBuilder(Blocks.COBBLESTONE, Blocks.STONE, 4, 2, 0, 2).build());
        STAR_FRUIT = register("star_fruit", Feature.TREE, treeBuilder(Blocks.OAK_PLANKS, Blocks.GOLD_BLOCK, 4, 2, 0, 2).build());
    }

    private static <FC extends FeatureConfiguration> Holder<ConfiguredFeature<FC, ?>> register(String name, Feature<FC> feature, FC config) {
        return FeatureUtils.register(PVZReborn.MOD_ID_WITH_COLON + name, feature, config);
    }

    private static TreeConfigurationBuilder treeBuilder(Block trunkProvider, Block foliageProvider, int baseHeight, int heightRandA, int heightRandB, int radius) {
        return new TreeConfigurationBuilder(BlockStateProvider.simple(trunkProvider),
                new StraightTrunkPlacer(baseHeight, heightRandA, heightRandB),
                BlockStateProvider.simple(foliageProvider),
                new BlobFoliagePlacer(ConstantInt.of(radius), ConstantInt.of(0), 3),
                new TwoLayersFeatureSize(1, 0, 1)
        );
    }

    public static class Placements {

        public static Holder<PlacedFeature> CHERRY, NUT, STAR_FRUIT;

        public static void registerPlacement() {
            CHERRY = register("cherry", TreeFeatures.CHERRY);
            NUT = register("nut", TreeFeatures.NUT);
            STAR_FRUIT = register("star_fruit", TreeFeatures.STAR_FRUIT);
        }

        private static Holder<PlacedFeature> register(String name, Holder<? extends ConfiguredFeature<?, ?>> feature) {
            return PlacementUtils.register(PVZReborn.MOD_ID_WITH_COLON + name,
                    feature,
                    InSquarePlacement.spread(),
                    VegetationPlacements.TREE_THRESHOLD,
                    PlacementUtils.HEIGHTMAP_OCEAN_FLOOR,
                    PlacementUtils.filteredByBlockSurvival(Blocks.OAK_SAPLING)
            );
        }

    }

}
